package com.modular.iot.bo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.ToolOpt;
import com.modular.iot.bean.DataFactorDo;
import lombok.Data;
import ntd.protocol.bo.Ntd212BO;
import ntd.util.modular.data.util.handle.constant.Constant212;
import com.c.Constant;
import ntd.util.modular.things.entity.DeviceData;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * IOT 设备数据
 */
@Data
public class IotData {

    /** 数据id */
    private String id;
    /** 原始报文 */
    private String originMsg;
    /** 设备编号 */
    private String mn;
    /** 数据类型 */
    private String cn;
    /** 系统类型 */
    private String st;
    /** 上报时间 */
    private LocalDateTime reportTime;
    /** 设备数据 - item */
    private List<IotDataItem> iotDataItems = new ArrayList<>();
    /** 数据来源ip */
    private String originIp;
    /** 租户id */
    private String tenantId;
    /** 基站名称 */
    private String name;
    /** 设备状态  0：离线，1：在线 */
    private Integer status;

    /**
     * 平台数据转换iot
     * @param deviceData
     * @return
     */
    public static IotData transformComPlatform(DeviceData deviceData) {
        IotData iotData = new IotData();
        BeanUtil.copyProperties(deviceData, iotData);
        iotData.setMn(deviceData.getDeviceCode());
        return iotData;
    }

    /**
     * 添加数据详情
     * @param iotDataItem
     */
    public void addDataItem(IotDataItem iotDataItem) {
        Opt.ofNullable(iotDataItem).ifPresent(iotDataItems::add);
    }

    public static IotData transformProvincePlatformData(JSONObject data) {
        IotData iotData = new IotData();
        iotData.setMn(data.getStr("StationId"));
        iotData.setReportTime(data.getLocalDateTime("MeasureDate", LocalDateTime.now()));
        iotData.setIotDataItems(CollStreamUtil.toList(data.getJSONArray("HourDataList"), o ->
                IotDataItem.transformProvincePlatformData(JSONUtil.parseObj(o))));
        return iotData;
    }

    public static IotData transform212(Ntd212BO ntd212BO) {
        Map<String, String> cpData = ntd212BO.getCPData();

        IotData iotData = new IotData();
        iotData.setMn(ntd212BO.getMN());
        iotData.setReportTime(LocalDateTimeUtil.parse(cpData.get("DataTime"), Constant.DATE_FORMAT_WLW_TWO));
        iotData.setCn(ntd212BO.getCN());
        iotData.setSt(ntd212BO.getST());

        Map<String, IotDataItem> dataItemMap = new HashMap<>();

        // 封装子项数据
        for (Map.Entry<String, String> entry : cpData.entrySet()) {
            if (StrUtil.endWith(entry.getKey(), Constant212.CP_AVG)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_AVG, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorVal(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_FLAG)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_FLAG, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorFlag(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_RTD)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_RTD, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValRtd(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_MIN)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_MIN, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValMin(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_MAX)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_MAX, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValMax(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_COU)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_COU, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValCou(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_ZS_RTD)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_ZS_RTD, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValZsRtd(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_ZS_MIN)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_ZS_MIN, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValZsMin(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_ZS_MAX)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_ZS_MAX, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValZsMax(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_ZS_AVG)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_ZS_AVG, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorValZsAvg(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_E_FLAG)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_E_FLAG, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactorEflag(entry.getValue());
            } else if (StrUtil.endWith(entry.getKey(), Constant212.CP_ERR)) {
                String factorCode = StrUtil.subBefore(entry.getKey(), Constant212.CP_ERR, false);
                IotDataItem iotDataItem = getIotDataItem(dataItemMap, factorCode);
                iotDataItem.setFactoryErr(entry.getValue());
            }
        }

        iotData.setIotDataItems(ListUtil.toList(dataItemMap.values()));

        return iotData;
    }

    /**
     * 数据item封装
     * @param dataItemMap
     * @param factorCode
     * @return
     */
    private static IotDataItem getIotDataItem(Map<String, IotDataItem> dataItemMap, String factorCode) {
        DataFactorDo dataFactorByCode = ToolOpt.OPT_D_FACTOR.getByCode(factorCode);

        IotDataItem iotDataItem = dataItemMap.get(dataFactorByCode.getCode());

        if (ObjectUtil.isNull(iotDataItem)) {
            iotDataItem = new IotDataItem();
            iotDataItem.setFactorCode(dataFactorByCode.getCode());
            iotDataItem.setFactorName(dataFactorByCode.getName());
            dataItemMap.put(dataFactorByCode.getCode(), iotDataItem);
        }

        return iotDataItem;
    }
}
